//
//  CombineIAPManager.swift
//  Combine-IAP-Demo
//
//  Created by garvin on 2025/1/7.
//

import Foundation
import StoreKit
import Combine

// MARK: - CombineIAPManager 主类
/// 基于Combine的内购管理器
/// 封装StoreKit 1.0的复杂性，提供简洁的响应式API
public final class CombineIAPManager: NSObject {
    
    // MARK: - 单例实例
    /// 全局共享实例
    public static let shared = CombineIAPManager()
    
    // MARK: - Combine Publishers
    /// 交易状态更新的Publisher
    /// 持续发布所有交易状态变化
    public var transactionUpdates: AnyPublisher<SKPaymentTransaction, Never> {
        transactionSubject.eraseToAnyPublisher()
    }
    
    /// 购买状态更新的Publisher
    /// 发布当前购买操作的状态变化
    public var purchaseStateUpdates: AnyPublisher<PurchaseState, Never> {
        purchaseStateSubject.eraseToAnyPublisher()
    }
    
    // MARK: - 私有属性
    /// 交易更新的Subject
    private let transactionSubject = PassthroughSubject<SKPaymentTransaction, Never>()
    
    /// 购买状态的Subject
    private let purchaseStateSubject = PassthroughSubject<PurchaseState, Never>()
    
    /// 当前的产品请求
    private var currentProductRequest: SKProductsRequest?
    
    /// 产品请求的Promise，用于Future操作
    private var productRequestPromise: ((Result<SKProduct, IAPError>) -> Void)?
    
    /// 当前购买的产品，用于状态跟踪
    private var currentPurchaseProduct: SKProduct?
    
    /// Combine订阅的存储
    private var cancellables = Set<AnyCancellable>()
    
    /// 队列，用于线程安全操作
    private let queue = DispatchQueue(label: "com.combine-iap.manager", qos: .userInitiated)
    
    // MARK: - 初始化
    /// 私有初始化，确保单例模式
    private override init() {
        super.init()
        setupTransactionObserver()
    }
    
    deinit {
        stopTransactionObserver()
    }
}

// MARK: - 公开API方法
extension CombineIAPManager {
    
    /// 加载单个产品信息
    /// - Parameter productID: 产品标识符
    /// - Returns: 返回产品信息的Publisher
    public func loadProduct(productID: String) -> AnyPublisher<SKProduct, IAPError> {
        return Future<SKProduct, IAPError> { [weak self] promise in
            self?.queue.async {
                self?.loadProductInternal(productID: productID, promise: promise)
            }
        }
        .eraseToAnyPublisher()
    }
    
    /// 购买指定产品
    /// - Parameter product: 要购买的产品
    /// - Returns: 返回购买状态的Publisher
    public func purchase(_ product: SKProduct) -> AnyPublisher<PurchaseState, IAPError> {
        return Future<PurchaseState, IAPError> { [weak self] promise in
            self?.queue.async {
                self?.purchaseInternal(product, promise: promise)
            }
        }
        .merge(with: purchaseStateUpdates.setFailureType(to: IAPError.self))
        .eraseToAnyPublisher()
    }
    
    /// 恢复购买
    /// - Returns: 返回恢复的交易列表
    public func restorePurchases() -> AnyPublisher<[SKPaymentTransaction], IAPError> {
        return Future<[SKPaymentTransaction], IAPError> { [weak self] promise in
            self?.queue.async {
                self?.restorePurchasesInternal(promise: promise)
            }
        }
        .eraseToAnyPublisher()
    }
    
    /// 检查是否可以进行购买
    /// - Returns: 是否支持购买
    public func canMakePayments() -> Bool {
        return SKPaymentQueue.canMakePayments()
    }
}

// MARK: - 私有实现方法
private extension CombineIAPManager {
    
    /// 设置交易观察者
    func setupTransactionObserver() {
        SKPaymentQueue.default().add(self)
        print("🛒 IAP交易监听已启动")
    }
    
    /// 停止交易观察者
    func stopTransactionObserver() {
        SKPaymentQueue.default().remove(self)
        print("🛒 IAP交易监听已停止")
    }
    
    /// 内部产品加载实现
    func loadProductInternal(productID: String, promise: @escaping (Result<SKProduct, IAPError>) -> Void) {
        // 取消之前的请求
        currentProductRequest?.cancel()
        
        // 保存Promise引用
        productRequestPromise = promise
        
        // 创建产品请求
        let request = SKProductsRequest(productIdentifiers: Set([productID]))
        request.delegate = self
        currentProductRequest = request
        
        // 开始请求
        request.start()
        
        print("🛒 开始请求产品信息: \(productID)")
    }
    
    /// 内部购买实现
    func purchaseInternal(_ product: SKProduct, promise: @escaping (Result<PurchaseState, IAPError>) -> Void) {
        guard canMakePayments() else {
            promise(.failure(.storeUnavailable))
            return
        }
        
        // 设置当前购买产品
        currentPurchaseProduct = product
        
        // 创建支付请求
        let payment = SKPayment(product: product)
        
        // 发布购买开始状态
        purchaseStateSubject.send(.purchasing)
        
        // 添加到支付队列
        SKPaymentQueue.default().add(payment)
        
        print("🛒 开始购买产品: \(product.productIdentifier)")
        
        // 由于购买是异步的，这里先发送purchasing状态
        // 实际的购买结果会通过transactionObserver回调处理
        promise(.success(.purchasing))
    }
    
    /// 内部恢复购买实现
    func restorePurchasesInternal(promise: @escaping (Result<[SKPaymentTransaction], IAPError>) -> Void) {
        // StoreKit 1.0的恢复购买是异步的，需要通过delegate处理
        // 这里先返回空数组，实际实现需要更复杂的状态管理
        SKPaymentQueue.default().restoreCompletedTransactions()
        print("🛒 开始恢复购买")
        
        // 暂时返回空数组，实际实现需要收集恢复的交易
        promise(.success([]))
    }
}

// MARK: - SKProductsRequestDelegate 实现
extension CombineIAPManager: SKProductsRequestDelegate {
    
    /// 产品请求成功回调
    public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
        queue.async { [weak self] in
            // 检查是否有产品返回
            if let product = response.products.first {
                print("🛒 产品信息获取成功: \(product.productIdentifier)")
                print("🛒 产品详情: \(product.detailedInfo)")
                
                // 验证产品有效性
                guard product.isValid else {
                    print("❌ 产品信息无效")
                    self?.productRequestPromise?(.failure(.productNotFound))
                    return
                }
                
                // 返回成功结果
                self?.productRequestPromise?(.success(product))
            } else {
                print("❌ 未找到产品信息")
                self?.productRequestPromise?(.failure(.productNotFound))
            }
            
            // 清理请求状态
            self?.cleanupProductRequest()
            
            // 打印无效的产品ID（调试用）
            if !response.invalidProductIdentifiers.isEmpty {
                print("❌ 无效的产品ID: \(response.invalidProductIdentifiers)")
            }
        }
    }
    
    /// 产品请求失败回调
    public func request(_ request: SKRequest, didFailWithError error: Error) {
        queue.async { [weak self] in
            print("❌ 产品请求失败: \(error.localizedDescription)")
            
            // 转换错误类型
            let iapError: IAPError
            if let skError = error as? SKError {
                switch skError.code {
                case .paymentCancelled:
                    iapError = .userCancelled
                case .paymentNotAllowed, .storeProductNotAvailable:
                    iapError = .storeUnavailable
                default:
                    iapError = .productRequestFailed(underlying: error)
                }
            } else {
                iapError = .productRequestFailed(underlying: error)
            }
            
            // 返回错误结果
            self?.productRequestPromise?(.failure(iapError))
            
            // 清理请求状态
            self?.cleanupProductRequest()
        }
    }
    
    /// 请求完成回调
    public func requestDidFinish(_ request: SKRequest) {
        print("🛒 产品请求已完成")
    }
}

// MARK: - 产品请求相关私有方法
private extension CombineIAPManager {
    
    /// 清理产品请求状态
    func cleanupProductRequest() {
        currentProductRequest?.cancel()
        currentProductRequest = nil
        productRequestPromise = nil
    }
}

// MARK: - SKPaymentTransactionObserver 实现
extension CombineIAPManager: SKPaymentTransactionObserver {
    
    /// 交易状态更新回调
    /// 这是StoreKit处理购买流程的核心方法
    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        self.queue.async { [weak self] in
            for transaction in transactions {
                self?.handleTransaction(transaction)
            }
        }
    }
    
    /// 处理恢复购买完成
    public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {
        self.queue.async { [weak self] in
            print("🛒 恢复购买完成")
            // 可以在这里处理恢复购买的逻辑
        }
    }
    
    /// 处理恢复购买失败
    public func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {
        self.queue.async { [weak self] in
            print("❌ 恢复购买失败: \(error.localizedDescription)")
            // 可以在这里处理恢复购买失败的逻辑
        }
    }
}

// MARK: - 交易处理相关私有方法
private extension CombineIAPManager {
    
    /// 处理单个交易
    /// - Parameter transaction: 交易对象
    func handleTransaction(_ transaction: SKPaymentTransaction) {
        print("🛒 处理交易状态: \(transaction.transactionState.rawValue) - 产品: \(transaction.payment.productIdentifier)")
        
        // 发送交易更新到所有订阅者
        transactionSubject.send(transaction)
        
        // 根据交易状态进行处理
        switch transaction.transactionState {
        case .purchasing:
            handlePurchasingTransaction(transaction)
        case .purchased:
            handlePurchasedTransaction(transaction)
        case .failed:
            handleFailedTransaction(transaction)
        case .restored:
            handleRestoredTransaction(transaction)
        case .deferred:
            handleDeferredTransaction(transaction)
        @unknown default:
            print("⚠️ 未知的交易状态: \(transaction.transactionState.rawValue)")
        }
    }
    
    /// 处理购买中状态
    func handlePurchasingTransaction(_ transaction: SKPaymentTransaction) {
        print("🛒 正在购买: \(transaction.payment.productIdentifier)")
        
        // 检查是否是当前购买的产品
        if isCurrentPurchaseTransaction(transaction) {
            purchaseStateSubject.send(.purchasing)
        }
    }
    
    /// 处理购买成功状态
    func handlePurchasedTransaction(_ transaction: SKPaymentTransaction) {
        print("✅ 购买成功: \(transaction.payment.productIdentifier)")
        
        // 检查是否是当前购买的产品
        if isCurrentPurchaseTransaction(transaction) {
            purchaseStateSubject.send(.purchased(transaction: transaction))
            // 清理当前购买状态
            currentPurchaseProduct = nil
        }
        
        // 完成交易（重要：防止重复提示购买）
        SKPaymentQueue.default().finishTransaction(transaction)
        
        // 这里可以添加收据验证逻辑
        // validateReceipt(for: transaction)
    }
    
    /// 处理购买失败状态
    func handleFailedTransaction(_ transaction: SKPaymentTransaction) {
        let errorMessage = transaction.error?.localizedDescription ?? "未知错误"
        print("❌ 购买失败: \(transaction.payment.productIdentifier) - \(errorMessage)")
        
        // 转换错误类型
        let iapError = convertSKErrorToIAPError(transaction.error)
        
        // 检查是否是当前购买的产品
        if isCurrentPurchaseTransaction(transaction) {
            purchaseStateSubject.send(.failed(error: iapError))
            // 清理当前购买状态
            currentPurchaseProduct = nil
        }
        
        // 完成交易
        SKPaymentQueue.default().finishTransaction(transaction)
    }
    
    /// 处理恢复购买状态
    func handleRestoredTransaction(_ transaction: SKPaymentTransaction) {
        print("🔄 恢复购买: \(transaction.payment.productIdentifier)")
        
        // 完成交易
        SKPaymentQueue.default().finishTransaction(transaction)
        
        // 这里可以添加恢复购买的特殊处理逻辑
    }
    
    /// 处理延期购买状态（如家庭共享等待批准）
    func handleDeferredTransaction(_ transaction: SKPaymentTransaction) {
        print("⏳ 购买延期: \(transaction.payment.productIdentifier)")
        
        // 检查是否是当前购买的产品
        if isCurrentPurchaseTransaction(transaction) {
            purchaseStateSubject.send(.deferred)
        }
        
        // 注意：延期的交易不应该调用finishTransaction
        // 等待用户批准后会变为purchased或failed状态
    }
    
    /// 检查是否是当前购买的交易
    func isCurrentPurchaseTransaction(_ transaction: SKPaymentTransaction) -> Bool {
        return currentPurchaseProduct?.productIdentifier == transaction.payment.productIdentifier
    }
    
    /// 将SKError转换为IAPError
    func convertSKErrorToIAPError(_ error: Error?) -> IAPError {
        guard let skError = error as? SKError else {
            return .purchaseFailed(underlying: error ?? NSError(domain: "Unknown", code: 0))
        }
        
        switch skError.code {
        case .paymentCancelled:
            return .userCancelled
        case .paymentNotAllowed:
            return .storeUnavailable
        case .storeProductNotAvailable:
            return .productNotFound
        case .cloudServiceNetworkConnectionFailed:
            return .networkError
        default:
            return .purchaseFailed(underlying: skError)
        }
    }
} 
